using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Acms.AcmsControls
{
    public abstract class BaseContentControlDisplay : CompositeControl
    {
        protected abstract BaseContentControlProperties GetProperties();
        protected abstract void SetProperties(BaseContentControlProperties properties);

        private void LoadData(System.Xml.XmlDocument xmlDocument)
        {
            if (xmlDocument != null)
            {
                BaseContentControlProperties tmpProp = GetProperties();
                System.Xml.Serialization.XmlSerializer xmls = new System.Xml.Serialization.XmlSerializer(tmpProp.GetType());
                SetProperties((BaseContentControlProperties)xmls.Deserialize(new System.IO.StringReader(xmlDocument.OuterXml)));
            }
        }

        public void LoadData(Acms.Bll.PostControl postControl)
        {
            try
            {
                LoadData(postControl.Value);
            }
            catch(System.Xml.XmlException e)
            {
                throw new Acms.Exceptions.ContentControlException(string.Format("Failed to load Xml Data for PostControlId '{0}' : {1}", postControl.Id, e.Message));
            }
        }

        public void LoadData(Acms.Bll.UnusedPostControl postControl)
        {
            try
            {
                LoadData(postControl.Value);
            }
            catch (System.Xml.XmlException e)
            {
                throw new Acms.Exceptions.ContentControlException(string.Format("Failed to load Xml Data for PostControlId '{0}' : {1}", postControl.Id, e.Message));
            }

        }

        private string controlName;
        public string ControlName
        {
            get { return controlName; }
            set { controlName = value; }
        }

        public sealed override void DataBind()
        {
            Acms.Bll.PostControl postControl = null;
            BaseTemplateControl template = FindTemplateControl(this.NamingContainer);
            //find containg BaseTemplateControl
            //else not there find page

            if (template != null)
            {
                postControl = template.FindPostControl(this.ControlName);
            }
            else if (this.Page is TemplatePage)
            {
                postControl = ((TemplatePage)Page).CurrentPost.FindPostControl(this.ControlName);
            }
            else
            {
                throw new ApplicationException("Could not find Template. All Content Controls must be exists in a Template which inherits from BaseTemplateControl");
            }

            if (postControl != null)
            {
                LoadData(postControl);
            }
            EnsureChildControls();
            DataBindChildren();
            requiresDataBinding = false;
        }

        private BaseTemplateControl FindTemplateControl(Control control)
        {
            if(control == null)
            {
                return null;
            }
            else if (control is BaseTemplateControl)
            {
                return control as BaseTemplateControl;
            }
            else
            {
                return FindTemplateControl(control.NamingContainer);
            }
        }


        bool requiresDataBinding = true;
        public void SetRequiresDatabinding()
        {
            requiresDataBinding = true;
        }

        protected override object SaveViewState()
        {
            ViewState["requiresDataBinding"] = requiresDataBinding;
            return base.SaveViewState();
        }

        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);
            if(ViewState["requiresDataBinding"] is bool)
                requiresDataBinding = (bool)ViewState["requiresDataBinding"];
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            if (requiresDataBinding)
                DataBind();
        }
    }
}
